import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
import { ObjectRet, ResponseData } from "./response";
import { getAccessToken, getRefreshToken, setToken } from "@/utils/cacheUtils";
import { usePermissionStore } from "@/store";
import { RefreshLoginRet } from "./login";

export const baseURL: string = import.meta.env.VITE_APP_BASE_API;

const service = axios.create({
  baseURL: baseURL,
});

//请求拦截器
service.interceptors.request.use((config) => {
  //这里就是配置 axiox 请求api的时候,带上的token
  if (!config.headers.Authorization) {
    config.headers.Authorization = getAccessToken();
  }
  if (config.url.startsWith("v1")) {
    config.headers.workflow = true;
    config.baseURL = config.baseURL.replace("api", "");
  }
  return config;
});

//响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse<ResponseData>) => {
    // 检查配置的响应类型是否为二进制类型（'blob' 或 'arraybuffer'）, 如果是，直接返回响应对象
    if (response.config.responseType === "blob" || response.config.responseType === "arraybuffer") {
      return response;
    }
    // 检查响应头中的 Content-Type
    const contentType = response.headers["content-type"] || "";
    // 判断是否为 HTML 类型  Else工作流需要
    if (contentType.includes("text/html")) {
      return response.data;
    }
    if (response.config.headers["workflow"] == "true") {
      return response.data;
    }
    const { status, body, message } = response.data;
    if (status === 200) {
      return body;
    } else if (status === 400) {
      // 表单校验错误
      ElMessageBox({
        title: "错误",
        message: h(
          "pre",
          { style: "text-wrap: wrap;background: #112435;color: #f08047;" },
          JSON.stringify(body.errors, null, "\t")
        ),
      });
      return Promise.reject(JSON.stringify(body.errors));
    } else if (status === 500) {
      // 后台所有异常
      ElMessageBox({
        type: "error",
        message: JSON.parse(message),
      });
      return Promise.reject(message);
    } else {
      ElMessage.error(message || "系统出错");
      return Promise.reject(message);
    }
  },
  async (error) => {
    if (!error) {
      return;
    }
    const permissionStore = usePermissionStore();
    if (!error.response) {
      ElMessage.error(error.message);
      return Promise.reject(error.message);
    }
    let { status, data, statusText } = error.response;
    if (status === 401) {
      if (data) {
        if (error.config.responseType === "blob" || error.config.responseType === "arraybuffer") {
          const bufferStr = new TextDecoder("utf-8").decode(data);
          data = JSON.parse(bufferStr);
        }
        const { status: code, message } = data;
        if (code === 4000) {
          //需要刷新token
          return await refreshLogin(error);
        } else if (code === 4001) {
          //需要重新登录
          ElMessageBox.confirm(message, "提示", {
            confirmButtonText: "确定",
            type: "warning",
          }).then(() => {
            permissionStore.resetRouter();
          });
        } else {
          permissionStore.resetRouter();
        }
      } else {
        permissionStore.resetRouter();
      }
    } else if (status === 403) {
      ElMessage.error(data.message || "系统出错");
    } else if (status === 429) {
      ElMessage.error(data.message || "系统出错");
    } else {
      ElMessage.error(statusText || "系统出错");
    }
    return Promise.reject(error.message);
  }
);

//刷新token
const refreshLogin = async (error) => {
  const permissionStore = usePermissionStore();
  const config = { ...error.config };
  config.url = baseURL + "/Login/RefreshLogin";
  config.headers.Authorization = getRefreshToken();
  config.method = "GET";
  config.responseType = "json";
  const { success, data, message } = await service<AxiosRequestConfig, ObjectRet<RefreshLoginRet>>(
    config
  );
  if (success) {
    setToken(data.accessToken, data.refreshToken);
    error.config.headers.Authorization = getAccessToken();
    return await service(error.config);
  } else {
    permissionStore.resetRouter();
  }
};

export default service;
